// iostream standard header

#ifndef _BINARYSTREAM_H_
#define _BINARYSTREAM_H_
#include <iosfwd>
#include <iostream>
template <class T, class C> class CBinary_basic_istream
{
private:
	T& strm;
public:
	CBinary_basic_istream(T& t) :strm(t){}
	CBinary_basic_istream& operator>>(char& X)
		{strm.read((C*)&X, sizeof X); return *this;}
	CBinary_basic_istream& operator>>(bool& b)
		{char X; strm.read((C*)&X, sizeof X); b = (X!=0);return *this;}
	CBinary_basic_istream& operator>>(short& X)
		{strm.read((C*)&X, sizeof X); return *this;}
	CBinary_basic_istream& operator>>(unsigned short& X)
		{strm.read((C*)&X, sizeof X); return *this;}
	CBinary_basic_istream& operator>>(int& X)
		{strm.read((C*)&X, sizeof X); return *this;}
	CBinary_basic_istream& operator>>(unsigned int& X)
		{strm.read((C*)&X, sizeof X); return *this;}
	CBinary_basic_istream& operator>>(long& X)
		{strm.read((C*)&X, sizeof X); return *this;}
	CBinary_basic_istream& operator>>(unsigned long& X)
		{strm.read((C*)&X, sizeof X); return *this;}
	CBinary_basic_istream& operator>>(float& X)
		{strm.read((C*)&X, sizeof X); return *this;}
	CBinary_basic_istream& operator>>(double& X)
		{strm.read((C*)&X, sizeof X); return *this;}
	CBinary_basic_istream& operator>>(long double& X)
		{strm.read((C*)&X, sizeof X); return *this;}
	CBinary_basic_istream& operator>>(std::string& X);
	T& GetStream() {return strm;}
	const T& GetStream() const {return strm;}
    operator void * () const
		{return strm.operator void *();}
    bool operator ! () const
		{return !strm;}
    std::ios_base::iostate rdstate() const
		{return strm.rdstate();}
    void clear(std::ios_base::iostate state = std::ios_base::goodbit)
		{return strm.rdstate();}
    void setstate(std::ios_base::iostate state)
		{strm.setstate(state);}
    bool good() const
		{return strm.good();}
    bool eof() const
		{return strm.eof();}
    bool fail() const
		{return strm.fail();}
    bool bad() const
		{return strm.bad();}
};

template <class T, class C> class CBinary_basic_ostream
{
private:
	T& strm;
public:
	CBinary_basic_ostream(T& t) :strm(t){}
    CBinary_basic_ostream& operator<<(char x)
		{strm.write((const C*)&x, sizeof x); return *this;}
    CBinary_basic_ostream& operator<<(bool b)
		{char x = b;strm.write((const C*)&x, sizeof x); return *this;}
    CBinary_basic_ostream& operator<<(short x)
		{strm.write((const C*)&x, sizeof x); return *this;}
    CBinary_basic_ostream& operator<<(unsigned short x)
		{strm.write((const C*)&x, sizeof x); return *this;}
    CBinary_basic_ostream& operator<<(int x)
		{strm.write((const C*)&x, sizeof x); return *this;}
    CBinary_basic_ostream& operator<<(unsigned int x)
		{strm.write((const C*)&x, sizeof x); return *this;}
    CBinary_basic_ostream& operator<<(long x)
		{strm.write((const C*)&x, sizeof x); return *this;}
    CBinary_basic_ostream& operator<<(unsigned long x)
		{strm.write((const C*)&x, sizeof x); return *this;}
    CBinary_basic_ostream& operator<<(float x)
		{strm.write((const C*)&x, sizeof x); return *this;}
    CBinary_basic_ostream& operator<<(double x)
		{strm.write((const C*)&x, sizeof x); return *this;}
    CBinary_basic_ostream& operator<<(long double x)
		{strm.write((const C*)&x, sizeof x); return *this;}
	CBinary_basic_ostream& operator<<(const std::string& x)
		{	*this << (int)x.length();
			strm.write(x.c_str(), x.length());
			return *this;}
	T& GetStream() {return strm;}
	const T& GetStream() const {return strm;}
    operator void *() const
		{return strm.operator void *();}
    bool operator!() const
		{return !strm;}
    std::ios_base::iostate rdstate() const
		{return strm.rdstate();}
    void clear(std::ios_base::iostate state = std::ios_base::goodbit)
		{return strm.rdstate();}
    void setstate(std::ios_base::iostate state)
		{strm.setstate(state);}
    bool good() const
		{return strm.good();}
    bool eof() const
		{return strm.eof();}
    bool fail() const
		{return strm.fail();}
    bool bad() const
		{return strm.bad();}
};

template<class T, class C>
CBinary_basic_istream<T,C>& CBinary_basic_istream<T,C>::operator>>(std::string& X)
{
	int len;
	*this >> len;
	//arbitary value
	if (len > 1024 || len < 0)
	{
		strm.setstate(std::ios_base::badbit);
		return *this;
	}
	char* buf = new char[len+1];
	strm.read(buf, len);
	buf[len] = 0;
	X.assign(buf, len);
	delete[] buf;
	return *this;
}

typedef CBinary_basic_istream<std::istream, char> CBinary_istream;
typedef CBinary_basic_ostream<std::ostream, char> CBinary_ostream;
#endif //_BINARYSTREAM_H_


